Skip to content

ephemeral: Add a TPM 2.0 emulated by swtpm - #411

Merged
cgwalters merged 2 commits into
bootc-dev:mainfrom
yeetypete:feat/ephemeral-tpm-state
Oct 30, 2026
Merged

cgwalters merged 2 commits into
bootc-dev:mainfrom
yeetypete:feat/ephemeral-tpm-state

Conversation

@yeetypete

@yeetypete yeetypete commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Allow adding a TPM 2.0 to ephemeral bcvk VMs, emulated by swtpm:

  • --tpm attaches an ephemeral TPM. Its state is discarded with the container.

swtpm runs inside the container from the host's /usr, just like virtiofsd. QEMU attaches it as a tpm-tis device (tpm-tis-device on aarch64). This is the same tpm model bcvk libvirt run uses.

Added test_run_ephemeral_tpm which checks if the emulated TPM shows up under /dev/tpmrm0.

Assisted-by: AI

own helper.

Signed-off-by: Peter Siegel <psiegel2000@icloud.com>
@yeetypete

yeetypete commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor Author

Just for some more context on how this can be used for some e2e verified boot testing:

  1. You create an "installer vm" with bcvk ephemeral --tpm-state DIR with a mounted empty disk.
  2. Inside you set up the disk with LUKS and TPM and call bootc install to-filesystem on it.
  3. After creating a disk in the installer VM a 2nd vm can boot it reusing the previous TPM's state and unlock the disk unattended. This can be a systemd-vmspawn vm, etc.

The idea is that this emulates how you might set up a bare-metal device where the installer and the booted system post-install see the same TPM.

cgwalters
cgwalters previously approved these changes Oct 26, 2026

/// Wait until the process `name` creates `socket_path`. Fails if
/// `process` exits first or `timeout` passes.
async fn wait_for_socket(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For virtiofsd at least we should have always been using --fd to avoid any polling at all.

Something to improve in a followup


Mount disk file as virtio-blk device at /dev/disk/by-id/virtio-<name>

**--tpm**

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While this is the conservative default, I would argue to turn this on by default on supported architectures in the future

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it'll depend on swtpm being installed on the host but that should be easy to check.

Comment thread docs/src/man/bcvk-ephemeral-run.md Resolved
--tpm attaches a TPM 2.0 emulated by swtpm, whose state is discarded with
the container.

Signed-off-by: Peter Siegel <psiegel2000@icloud.com>
Assisted-by: AI
@cgwalters
cgwalters merged commit 76dc9d8 into bootc-dev:main Oct 30, 2026
30 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

swtpm can inherit pipe writers and cause shutdown hangs, while premature validation rejects virtiofs configurations before their socket directories are created.

2 open issues
What changed in this PR

Adds opt-in, ephemeral TPM 2.0 support to container-backed VMs using swtpm alongside QEMU.

Changes:

  • Adds --tpm and architecture-specific QEMU TPM devices.
  • Manages swtpm startup and reuses socket-readiness handling for virtiofsd.
  • Documents the option and adds an integration test checking /dev/tpmrm0.
File Description
docs/​src/​man/​bcvk-ephemeral-test-basic.md Documents --tpm for basic tests.
docs/​src/​man/​bcvk-ephemeral-run.md Documents --tpm for ephemeral runs.
docs/​src/​man/​bcvk-ephemeral-run-ssh.md Documents --tpm for SSH runs.
crates/​kit/​src/​varlink_ipc.rs Keeps TPM disabled for Varlink-created VMs.
crates/​kit/​src/​to_disk.rs Keeps TPM disabled for disk installation.
crates/​kit/​src/​run_ephemeral.rs Adds the CLI option and TPM configuration.
crates/​integration-tests/​src/​tests/​run_ephemeral_ssh.rs Tests TPM device availability in the guest.
crates/​bcvk-qemu/​src/​qemu.rs Adds swtpm management, TPM devices, and shared readiness checks.
crates/​bcvk-qemu/​src/​lib.rs Exports TpmConfig.

Review effort: Balanced

let mut cmd = tokio::process::Command::from(cmd);
cmd.kill_on_drop(true);
debug!("{cmd:?}");
let child = cmd.spawn().context("Failed to spawn swtpm")?;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm we should definitely not be opening fds without O_CLOEXEC that sounds like a bug if so

impl RunningQemu {
/// Spawn QEMU with the given configuration.
pub async fn spawn(mut config: QemuConfig) -> Result<Self> {
config.validate()?;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants